It depends on the purpose of this RAT and the techniques you intend to use. Using low level languages like C or C++ is not going to automatically make reverse engineering your binary harder. The key here is to understand what scenarios it’s designed to evade (Getting caught by AV, Network analysis, Manual reverse engineering), thinking about what techniques you want to use and then looking at your options.
If you want to do low-level stuff like import and section encryption, in-memory image loading, API hooks, code injection etc then yeah, C / C++ with some Assembly modules is probably the easiest way to go because they communicate directly with the native OS interfaces. Any of that stuff is obviously going to be OS-specific but you can encapsulate these parts.
C# and Powershell are not very far away from these interfaces, the CLR is very flexible and you can call any Windows API you’d like and load native code. There are PE and shellcode loaders for them, it just requires dealing with another layer of abstraction, casting data types, pointers and such. Detecting and dealing with different .Net versions is also quite a hassle. As for Powershell, it suffers from the same problems but at least your code runs under a recognized process.
I’d also consider Rust and Go, since they are both low-level (Rust is equivalent to C, Go has a GC and does some things in the background but still basically compiles to native code), modern, have good libraries / docs and nice wrappers for network and IO.