Regarding your question about why NL (Newline) and CR (Carriage Return) both need to be enabled in the Serial Monitor, check out page 5 of the datasheet here: https://www.electronicaestudio.com/docs/istd016A.pdf
The module is not waiting for "AT" as a command, for instance, but specifically "AT\r\n." The \r (Carriage Return) is a special character in a string that inserts a type of white space character similar to the signal an older electronic typewriter might use when the "Return" key is pressed to literally return the carriage (holding all the typeset dyes) to the far left to start a new line. More modern systems settled on the "Newline" white space character which you can add to a string with \n. It performs the same action in a word processor, but is separate as it does not signal anything needing to be physically moved to start the new line.
The HC-05 probably needs to be compatible with many systems and needs to parse incoming data with standard characters. Since the datasheet specifies "AT\r\n" and not "AT\n\r," I suspect the module takes a string of data into the register when the Newline character is received. It probably tolerates the Carriage Return character so it can be compatible with other systems.
The println() function literally tacks on a \n to the end of your string. And all characters, even white space characters, get copied from one serial port to the other with your code. So, switching to NL & CR mode in the Serial Monitor tacks on both \r and \n every time you send data.
As to why it sometimes works with just the println() function, I suspect you may have had the Serial Monitor in CR mode or, perhaps, we can get away with two \n characters.
You are using soft UART Port for the BT at 38400 Bd; but, the recommendation is: use soft UART Port at 9600 Bd. It is also known that the default Bd of HC05 is 9600. The following sketch of yours work well for my UNO + HC05 at 9600 Bd. There is no need to enter any AT command. I have used the connection diagram of Fig-1.
#include <SoftwareSerial.h>
SoftwareSerial mySerial(10, 11); // RX, TX
void setup()
{
Serial.begin(38400);
while (!Serial)
{
}
Serial.println("Enter AT Command");
mySerial.begin(38400);
}
void loop()
{
if (mySerial.available())
{
Serial.write(mySerial.read());
}
if (Serial.available())
{
mySerial.write(Serial.read());
}
}