The only reason not to use them for identifiers that are generated dynamically is because of memory concerns, as we will discuss bellow.
This doubt is very common because many programming languages don't have symbols, only strings, and thus strings are also used as identifiers in your software. You should be worrying about what symbols are meant to be, not only when you should use symbols. Symbols are meant to be identifiers. If you follow this philosophy, chances are that you will do things right.
There are several differences between the implementation of symbols and strings. The most important thing about symbols is that they are immutable. This means that they will never have their value changed. Because of this, symbols are instantiated faster than strings and some operations like comparing two symbols is also faster.
The fact that a symbol is immutable allows ruby use the same object every time you reference the symbol, saving memory. So every second time the interpreter reads :my_key it can take it from the memory instead of instantiate it again. This is less expansive than initializing a new string every time.
You can get a list all symbols that are already instantiated with the command Symbol.all_symbols.
For ruby versions before 2.2, once a symbol is instantiated, this memory will never be free again. The only way to free the memory is restarting the application. So symbols are also a major cause of memory leaks when used wrongly. The simplest way to generate a memory leak is using the method to_sym on user input data - since this data will always change, a new portion of the memory will be used forever in the software instance. Ruby 2.2 introduced the symbol garbage collector, which frees symbols generated dynamically, so the memory leaks generated by creating symbols dynamically it is not a concern any longer.