An efficient way to implement the connected components algorithm as mentioned by @mkrieger1 in the comments is to convert the list of sets to a set of hashable frozensets so that as you iterate through it and find a frozenset that intersects with the current one you can easily remove it from the pool:
pool = set(map(frozenset, l))
groups = []
while pool:
groups.append(set(pool.pop()))
while True:
for candidate in pool:
if groups[-1] & candidate:
groups[-1] |= candidate
pool.remove(candidate)
break
else:
break
Given l = [{1, 3}, {2, 3}, {4, 5}, {6, 5}, {7, 5}, {8, 9}], groups will become:
[{1, 2, 3}, {4, 5, 6, 7}, {8, 9}]
And given l = [{1, 2}, {3, 4}, {2, 3}], groups will become:
[{1, 2, 3, 4}]
And given l = [{1}, {2}, {1, 2}], groups will become:
[{1, 2}]