Some big RAM-hungry strings (and worse, Strings) in there - are you sure you're not running out of RAM?
(Debug prints are best done with conditional compilation, not runtime conditionals, and debug strings should be short)
Doing this "* Debug - GSM AT Reader - Started" and "* Debug - GSM AT Reader - Finished"
is pointless - your debug print routine could add the "Debug - ", and save RAM
You can't easily expand memory, but you can use the memory you have more sensibly. Serial.print ("DBG MSG"); uses eight bytes of RAM to store the string. Serial.print (F("DBG MSG")); uses no RAM to store the string.
How can I clear one char that is array? Because after I use the array I wanna kill it.
You'll probably find the code and storage requirements for such micro-managed memory management exceed the benefits.
Proper use of local variables wherever possible will make much of your memory management automatic.
The code is quite remarkable. It’s well laid out, uses sensible names and provides meaningful comments. I’m not used to seeing code like that here.
Use PROGMEM for any strings that you want to print.
Make constants such as your pin numbers const.
Eliminate any data you don’t need. There isn’t much, but it seems to me that you could get rid of InLoopFirstTime and put the associated logic at the end of setup().
I assume that most of your memory is being taken up by the libraries you use, but char GSM_at_Buffer[200] is on the large side and does not seem to be used for much. If you just want to compare the response against a set of expected values then you could do that character by character as it is received, if you want, rather than sitting there buffering characters until your timeout has expired and then try to parse the buffered text. In any case, there’s no point buffering content that is longer than the longest string you’re going to compare against it, is there?