track cycle participants per root
The search graph may have multiple roots, e.g. in
```
A :- B
B :- A, C
C :- D
D :- C
```
we first encounter the `A -> B -> A` cycle which causes `A` to be a root. We then later encounter the `C -> D -> C` cycle as a nested goal of `B`. This cycle is completely separate and `C` will get moved to the global cache. This previously caused us to use `[B, D]` as the `cycle_participants` for `C` and `[]` for `A`.
split off from #125167 as I would like to merge this change separately and will rebase that PR on top of this one. There is no test for this issue and I don't quite know how to write one. It is probably worth it to generalize the search graph to enable us to write unit tests for it.
r? `@compiler-errors`