I think this is quite a tricky problem, but interesting.
Here is a possibility using List.Reduce twice. It uses two Custom Nodes, but each of them is very simple. The only problem is keeping in mind how List.Reduce works.
You give List.Reduce a Function, a Seed and a List. It calls the Function once for each item in the List. At each call, the Function’s inputs are the current value of the seed and the item from the list; and it’s output is fed back in as the seed at the next call.
OuterGather’s List is your starting list, and it’s Seed/output is the exclusive list. In contrast, InnerGather’s List is the current state of the exclusive list, and it’s Seed is the current item from the starting list. InnerGather finds out if any items from the current exclusive list will match with the current item from the starting list, and so builds a new exclusive list that includes that item.
I had to use the Zebra package Logic.If in the InnerGather, since the built-in If node always Laces lists, and that wouldn’t have worked in this case.
The Home workspace:
Custom Node OuterGather:
Custom Node InnerGather: