I'm not sure what is considered the best approach, but one option would be to use instanced geometry - you provide the GPU with a 3d model and a list of places/orientations where you'd like it drawn (preferable in the form of a concatenated matrix), and the GPU will handle the rest via a custom vertex shader.
Basically, you create two vertex buffers: one containing your 3D model (a blade of grass or patch of sod, for instance), and one containing a list of transformation matrices, each matrix containing the scale+rotation+translation where you'd like to render an instance of your model. (You'll need a custom vertex structure to hold the matrix - it's a vertex buffer in name only, and is just used to pass matrices to the GPU.)
Then, you'll need a custom shader. The vertex shader will get called for each vertex in each stream, so for each call you'll get two input parameters: one vertex from your blade model, and one of the transformation matrices. The shader then transforms the model vertex with the matrix, and returns the updated position.
If you want effects like wind, etc, you can adjust the matrix for each instance and update the matrix stream.
Using a model for a patch of grass rather than individual blades is makes it easier to cull. If you're using an octree or BSP for collision and visibility determination, you can reduce the depth of your tree by dealing with larger "blocks" of grass instead of smaller blades. Also, it's easy to provide a less complex/less-detailed model for a patch of grass if you detect a performance issue.
There's also something called a "Geometry Shader" that may apply here, but I don't know anything about it other than it's relatively new and apparently (?) not supported on the xbox.
Here's a link to an XNA instancing sample.
Update
Alternate methods: Though rendering lots of grass via instancing is significantly faster than other geometry-based methods, it can still be very expensive. GPU Gems contains an interesting alternative using intersecting billboard clusters.
And, of course, there's shell rendering, which consists of rendering a stack of textured polys, each with a map of "dots" on a transparent background. Each texture has an image of a cross section of a patch of grass - think dots on a transparent background. When you render them in close proximity, the solid parts of the texture appear to be extruded and connected between the layers. Not sure how well this performs.
Update 2
I hadn't noticed that the XNA billboard sample is a grass simulation.