The reason you can't use string literals as template parameters is much simpler: mangling of symbol names for linking.
Each template function needs to be mangled to a different unique name. Since foo<"bar"> in two different translation units would still need to be linked to the same definition, it's necessary for the string (or a unique hash) to be used in the mangling. This either requires linkers to handle arbitrarily-long symbol names (a problem even now) or for someone to pick a suitable hash function that has such a low probability of collision that even the ridiculously huge codebases C++ committee members have to care about would never hit a collision.
This is also the reason that floating-point values aren't supported. Floating-point values can be calculated differently based on all kinds of compile-time flags, but you'd need to ensure that foo<2.0 * 0.3> always mangled to the same value, even if compiled in two different translation units with different floating-point flags.
You likewise cannot template on addresses or pointers, as their locations change with each compile (or link, or run) and hence cannot be mangled consistently. Functions can be used as template arguments only in cases where the compiler can resolve them to a specific function and not just a function pointer, even in constexpr situations, since compilers typically just add the function's mangled name to the template's mangled name.
These problems are solvable but C++ imposed these rules many years ago. Nobody has written or submitted a paper to the ISO C++ committee to add solutions and update the rules.
But what could happen in a worse case scenario? If it was allowed, then, could it happen that 2 exact same instances of a template would be created(because a new template instance is created for every combination of template parameters used in code), so, would that somehow pose a problem?
Yes. See the One Definition Rule. It's the same as why you wouldn't want an inline class member function to be compiled in two different translation units and then not be handled by the linker, resulting in two definitions in final output image and letting you get two entirely different results for &my_class::my_function. The definitions must be unique, which at the least means they must mangle the same so that the linker can determine that the definitions are duplicates and throw out all but one of them.
I'm not sure if that'd actually work though - I don't know if templated arguments can take constexpr values.
They can. That's half the point of even having constexpr values.