Assuming your code works for you, that's a good first step. A game that works is better than a game that doesn't. Players generally don't see or care about the game code.
Like a few others who requested reviews of their code, it looks like you have a few places that could be consolidated or eliminated.
In your menu scripts you have two single-function scripts and one empty script. Often a Unity UI script has a single class that responds to many different inputs, and buttons/sliders/etc from many UI panels all use that single script for their events.
You also have many one-line functions through the code that could probably be consolidated or eliminated. For example, colliding with a wall calls HandleEnterWallCollision(), which only has one line to call BounceBallAgainstWall(), which only has one line to call InverseVerticalMovement(), which only has one line to ChangeBallSpeed(), which only has one line to pass along to a different form of ChangeBallSpeed() that optionally caps the ball's speed by calling a one line RectifyBallSpeed() that changes a parameter to consolidate two values and pass along to a different RectifyBallSpeed(), which immediately splits out those same two parameters. Why all the redirection? If it bounces of a wall you know you need to play a sound and reverse vertical movement, nothing more. If you bounce of a paddle you play a sound, reverse horizontal movement, shift the direction of travel, and ensure the speed is appropriate. No need for the long chain of functions.
Along the same theme, you've broken up functionality that could be handled more generically. For example, the queries of CanMoveUp() and CanMoveDown() do nothing but return flags. Those flags are set and cleared every frame, even if they are never queried. Personally I'd rather allow code to send the move commands all they want, but when they set it always clamp the results to within the valid range. You only incur the cost of checking against up or down if they actually attempt to move, and that cost is a single clamp call.
The way you use Unity's 2D collision system means you end up with more scripts than you probably need. In Pong the only thing needing collision response is the ball. You've got them also on the PongController and the Goal objects. The ball controller already detects against wall and pong tags, you could add a goal tag to handle those, and remove the other two responses.
Dump the Start() and Update() functions if you aren't actually using them. Unity automatically generates them since they're used in so many scripts, but they have a small cost.
You have several variables that probably should be private --- you don't want others messing with the variable --- but you want them exposed in the inspector so you can attach a GameObject. Keep them private, but add the [SerializeField] attribute above the variable. For example:
public GameObject pauseMenu;
// could become
[SerializeField]
GameObject pauseMenu;
In larger projects you will want to wrap the scripts in namespaces. Sadly Unity doesn't automatically do this, by default new scripts are placed in the global namespace. Your project is small so it isn't really need it, but it is something to know about as your projects grow.
Since the game works for you that can be good enough. Most of these changes are minor structural changes to simplify the code.