You can solve any problem in a language without generics, such as Go, C, Fortran-IV, or any other Turing-complete language, including the Turing machine "assembly".
The difference is in speed of producing such code, amount of bugs introduced, ability to understand, modify, and evolve the code, etc.
Don't know Fortran, but while C doesn't have generics you're getting similar behavior due to macros (for example min(), max() are macros) and weak typing. So the need of having generics there is much weaker.
There are a number of tools (and the "go generate" construct) designed to support code generation. If you just want macro-level behavior, that's easy to do.
Yes, and that's what I'm currently doing, but it is essentially just automating writing the same code multiple times. It still has issues, like having to remember to regenerate the code on change, or making harder to use IDE features to refactor. There are also some limitations it has.
What would you call a language that forces you to write / use a preprocessor to introduce higher-level features?
Low-level. More specifically, low-level for the domain where you're working. C is admittedly low-level because it had to be minimal even for 1970 and close to the metal. Other languages usually enjoy less drastic design constraints.
The difference is in speed of producing such code, amount of bugs introduced, ability to understand, modify, and evolve the code, etc.