Deferred shading is only a technique to "deffer" the actual shading operation for later stages, this can be great to reduce the number of passes needed (for example) to render 10 lights which needs 10 passes. My point is regardless of the rendering technique you are using there are certain possible rendering optimizations that reduce the number of objects (vertices, normals etc) that your engine need to process.
There are no de facto standard for rendering optimizations, but rather a number of techniques that can be used interchangeably or together to achieve certain performance characteristics. Using each technique highly depends on the nature of the scene being rendered.
Even when using deferred rendering those technique apply and are widely used.
Frustum Culling
Only Objects that are fully or partially included in the view frustum, ever need to be submitted to the rendering pipeline. This is the basic concept of frustum culling, unfortunately checking if a mesh is in/out of the view frustum can be an expensive operation, so instead, engine designers use an approximate bounding volume like an AABB or a bounding sphere, even though this might not as accurate as using the actual mesh, the accuracy difference isn't worth the trouble of checking with the actual mesh.

Even with bounding volumes, you don't really need to check each one, alternatively you can construct a bounding volume hierarchy to do an earlier culling, using this is highly dependent on the complexity of the scene.
This is a good and a simple technique for a smaller engine. I recommend using a "normal" Bounding Volume/Frustum checking without hierarchies if you engine does not require rendering very complex scenes.

Back face culling
This is a must, why draw faces that won't be visible anyway? rendering API provide an interface to turn on/off back face culling. Unless you have a strong reason why not to turn it on, like some of the CAD applications this is a must do thing.
Occlusion Culling
Using the Z-buffer you can solve visibility determination. But the problem is that Z-buffer isn't always great in terms of performance, since Z-buffer can only be resolved at later stages of the pipeline, objects being occluded should be rasterized and might be written to the Z-buffer and the Color buffer before failing the Z test.
Occlusion culling solves this, by doing some early tests to cull occluded objects that are in the rendering frustum. One practical implementation of occlusion culling is using point-based queries and checking if certain objects are visible from a specific point view.

A great real world example of such technique is in GTA5, where the skyscrapers are stratigically placed at the center of the city, are not only decorations, they also work as occluders, effectively occluding the rest part of the city and preventing it from being rasterized.

Level of Detail
Level of detail is widely used technique, the idea is to use a simpler version of the mesh when the mesh is less contributing to the scene. there are too common implementations one simply switches the mesh with a simpler one when it's no longer greatly contributing, the mesh is selected based on some factor like the distance and the number of pixels (area on the scree) the mesh is occupying. The other version dynamically tessellates the mesh and is widely used in terrain rendering.

What if all of these didn't work ?
Well, that's a good question.
The first thing you need to do is to Profile your application using a graphics profiler, and determine where the bottleneck is. Keep in mind that the bottle neck may change based as the content being rendered change.
Bottlenecks might be also be part of the code running on CPU so you need to measure that too.
After that you need to do some optimization in the bottleneck keep in mind that there is no right answer for this, and will be different from hardware to another.
Some common GPU optimzation tricks:
- Avoid branching in shaders.
- Try different vertex structures for example {VNT} interleaved in the same array or {V},{N},{T} in different arrays.
- Use VBOs with the "right" amount of data. (depending on your hardware) but usually less draw calls are better.
- Draw scene front to back.
- Turn off Z-buffer at some points for example if an image doesn't need Z testing.
- Use compressed textures.
Some common CPU optimization tricks:
- Use inline functions for small functions.
- Use SIMD (Single instruction multiple data) when possible.
- Avoid cache unfriendly memory jumps.