I just saw a question like this the other day. I think the hard part here is you're looking for user_id/profile_id combinations where the user_id has every group_id that the profile_id has, no more and no less. So take the usual join and add some correlation to count the number of group_ids each profile/user has and make sure they match (this has been edited a few times):
select user_id, profile_id
from user_groups join profile_groups on
user_groups.group_id=profile_groups.group_id
group by user_id, profile_id
having count(user_groups.group_id) =
(select count(*) from profile_groups as pg where
pg.profile_id=profile_groups.profile_id)
and count(profile_groups.group_id) = (select count(*) from user_groups as ug where
ug.user_id=user_groups.user_id)
;
Here's a run which includes two profiles with three groups each, with one common group between them and a new user in the fourth profile:
sqlite> create table user_groups (user_id integer, group_id varchar);
sqlite> create table profile_groups (profile_id integer, group_id varchar);
sqlite> insert into user_groups values(1, 'group1');
sqlite> insert into user_groups values(1, 'group2');
sqlite> insert into user_groups values(1, 'group3');
sqlite> insert into user_groups values(2, 'group1');
sqlite> insert into user_groups values(2, 'group2');
sqlite> insert into user_groups values(3, 'group4');
sqlite> insert into user_groups values(4, 'group1');
sqlite> insert into user_groups values(4, 'group5');
sqlite> insert into user_groups values(4, 'group6');
sqlite>
sqlite> insert into profile_groups values (11, 'group1');
sqlite> insert into profile_groups values (11, 'group2');
sqlite> insert into profile_groups values (11, 'group3');
sqlite>
sqlite> insert into profile_groups values (21, 'group1');
sqlite> insert into profile_groups values (21, 'group2');
sqlite>
sqlite> insert into profile_groups values (22, 'group4');
sqlite>
sqlite> insert into profile_groups values (23, 'group1');
sqlite> insert into profile_groups values (23, 'group5');
sqlite> insert into profile_groups values (23, 'group6');
sqlite> select user_id, profile_id
...> from user_groups join profile_groups on
...> user_groups.group_id=profile_groups.group_id
...> group by user_id, profile_id
...> having count(user_groups.group_id) =
...> (select count(*) from profile_groups as pg where
...> pg.profile_id=profile_groups.profile_id)
...> and count(profile_groups.group_id) = (select count(*) from user_groups as ug where
...> ug.user_id=user_groups.user_id)
...> ;
1|11
2|21
3|22
4|23