There is an important distinction lacking from this thread, which is why there are so many answers. hopefully this will clear some things up.
get_viewport().size.x
get_viewport().size.y
The above retrieves the size dimensions of the viewport specifically. note that in godot, a viewport and the window are not always the same thing. sometimes a viewport is just a minimap, or a sniper scope view. in many first and third person games, it may be the size of the window itself, so it may not matter, but shrinking the viewport may not shrink the window the viewport is inside of if it isn't root. (root is the root viewport so it's like the whole window)
get_viewport() is a function of the node class, and is meant to retrieve the viewport the node is a child of, so the viewport returned will depend on which node or node script it's being called on or in. thus, using this requires being aware of where it is being called, lest it return something you didn't expect, and can only be used in or on nodes. maybe not a huge issue, ofc, but there you go.
ProjectSettings.get_setting("display/window/size/width"))
this will retrieve the values the project was set at in the editor. HOWEVER this value does not change when the window size changes at runtime, and changing this will only affect the window after the game restarts. it's a configuration setting.
OS.window_size
this talks with the operating system directly to get the window size. while it probably works, something feels off about bypassing inbuilt godot functionality. it'll return a vector xy for the size of the window.
get_tree().get_root().size.x
get_tree().get_root().size.y
this uses the root viewport, which is probably the best solution. it's an inbuilt godot feature, changing it's value will affect the entire window, and you will always at a glance be able to tell you are editing the actual full game window.