You haven't mentioned anything about which RDBMS you're using, any applicable table constraints, or how you'd like to resolve e.g. duplicate rows in A or rows in B with the same (user_id, event_date) and different (other_info), but here's a query to consider (tested on Oracle 12c):
select user_id, date_start, date_end, event_date, other_info
from (
select a.user_id, a.date_start, a.date_end, b.event_date, b.other_info, row_number() over (partition by a.user_id, a.date_start, a.date_end order by b.event_date) as rnum
from a left outer join b on (event_date >= date_start and event_date < date_end and a.user_id = b.user_id)
) where rnum = 1;
The basic idea is to take the query you already had, number the rows based on your criteria, and then only select the rows with the right number. You can easily extend this to stabilize which row of B is selected by e.g.
... row_number() over (partition by a.user_id, a.date_start, a.date_end order by b.event_date, b.other_info nulls last) as rnum
instead, or if you wanted the first 2 rows for each (user_id, date_start, date_end) you could do
) where rnum < 3;