If you want a simplest solution, you can just connect your 5V pin of Arduino to the 3.3V external power supply. It will work just fine on 3.3V and all of its GPIO pins will be 3.3V too.
Warning: You must be careful because if you plug your Arduino to the USB wire, you will instantly get the 5V on all the pins, so you will burn your ESP. So you will have to disconnect ESP during programming.
The easiest (and safe) way for me in this scenario is to just use a standalone ATMEGA328P-PU chip on a breadboard and connect it manually. You just have to plug in 4 capacitors, a 16M oscillator and a resistor and upload sketch using a programmer (like USBasp) and "Upload using a programmer" button. You can then safely run everything on 3.3V because the programmer has a jumper and can work on 3.3V too and you don't have to use ANY level shifters and or voltage dividers. In my case they were not even working (I don't know why). You connect such "environment" once on a breadboard and you can safely work with it later. Let me know if you need more info on this.
Warning: If you work with SPI bus (MISO, MOSI, SCK), like an SD card reader for example, then you must secure the SPI lines of the device (card reader) with resistors, because you may also burn your chip if 2 opposite signals are directed to the same line by 2 separate devices. I've burned my 328P like this once.
Warning: Don't use a programmer for supplying power to your circuit. It can work for programming, but when your ESP starts connecting to WiFi it will require much more power than the programmer can provide! In best scenario it will just not work and hang up or reset.