Many driver modules require large blocks of ram for queues and other data structures. These eat up a bunch of memory, even if that module is not used.
Consider moving the allocation of that ram outside of the module and assigned via an init function. This would allow ram to only be assigned to a module if it is enabled and otherwise that ram would be available for other modules instead.
As an example, the byte queues for the comms module are defined in main instead of in the comms module. This is also true for the stream queues that streamManager uses.
Modules to consider changing: spi, i2c, feedbackControl (the trajectory queue), eeprom.
Most other modules so far just implement moderate sized structs per channel. This is likely more work to recover.
I removed a big chunk out of packetReceiver. There was a queue of big buffers that did not need to be a queue and did not need to be so big.