Inner for loop when run in background in bash spawns new bash process

Because you have piped the loop into grep, it must be run in a subshell. This is mentioned in the Bash manual:

Each command in a pipeline is executed in its own subshell, which is a separate process (see Command Execution Environment)

It is possible to avoid that with the lastpipe shell option for the final command in the pipeline, but not any of the others. In any case, you've put the whole pipeline into the background, which also creates a subshell.

There is no way around this. What you're doing inherently does require separate shell processes in order to work: even ignoring the pipeline, creating a background process requires creating a process.

If your issue is the CPU usage, that's caused by running everything at once. If you remove the & after the grep, all the commands will run in sequence instead of simultaneously. There will still be subshells created (for the pipeline), but those are not themselves the main issue in that case. If you need them to run simultaneously, the increased CPU usage is the trade-off you've chosen.