I don't have the time right now to understand your code, but I think Sow[] and Reap[] might take care of your memory issue.
Here is a overly-simplified example of how Sow and Reap can be used in a situation like this:
f[x_] := Do[
With[
{
r = RandomInteger[i]
}
,
If[OddQ[r], Sow[r]]
]
,
{i, Abs[x]}
];
g[x_] := Reap[
Do[
With[
{
r = RandomInteger[i]
}
,
If[EvenQ[r], f[r]];
]
,
{i, Abs[x]}
];
] [[2]] // First;;
g[100]
This example wraps the outer Do[] with Reap[] which will collect only those values sowed by Sow[] in the inner Do[].
As I understand it, this technique will only retain in memory the values that you want to keep while immediately discarding those that fail the test.
Good luck, and have a great and safe rest of your weekend.