The fact that you're not throwing any exceptions, and the onClick.Invoke() is firing suggests that the issue is that some other element is consuming the clicks. Without having your project in front of me, I can only make some suggestions.
- Ensure that there are no ui elements in between the camera and the buttons(such as transparent panels or images); you can move around objects at run time to see if they're too close and consuming the click.
- Make sure that a parent canvas does not have a CanvasGroupwithInteractableset to false.
- Look for any empty objects/colliders/listeners that could be blocking raycasts.
Good luck!
Edit
After re-reading your code, and giving the linked post another once-through I have realized a mistake in your code.
In your GameOptions class constructor, you aren't actually referencing the instantiated object when collecting the objects. You wrote this:
this.canvas = canvas;
GameObject.Instantiate(canvas);
Text[] textObjects = canvas.GetComponentsInChildren<Text>();
If you look through what is exactly happening, you're assigning the field canvas to the prefab that was passed into the parameter of the constructor. After you make the assignment, you instantiate the prefab with the parameter, without any reference to the instantiated object.
After that you're calling GetComponentsInChildren on a prefab not the instantiated object itself. This is why onClick.Invoke() is being fired, because the objects exist on the prefab; they're just not the objects you're looking for.
I have refactored your constructor, which should solve your issue.
public GameOptions(GameObject canvas)
{
    //here we instantiate the canvas item, assigning it to the field
    this.canvas = GameObject.Instantiate(canvas);  
    //then we reference the field item, instead of the parameter item
    Text[] textObjects = this.canvas.GetComponentsInChildren<Text>();
    Button[] buttonObjects = this.canvas.GetComponentsInChildren<Button>();
    for(int i = 0; i < buttonObjects.Length; i++)
    {
        Debug.Log(buttonObjects[i].name);
        buttonObjects[i].onClick.AddListener(() => clicked());
        buttonObjects[i].onClick.Invoke();
    }
}
A Few Notes
- You should use a Canvasitem instead ofGameObject, even if you never use any members of theCanvasclass; it makes it easier to read later on down the road, and prevents you from accidentally constructingnew GameOptions(someRandomButton)which just wouldn't do anything when you tried to access the children. TheCanvasobject inherits fromGameObjectso you would have everything you need.
- You should consider using a different naming scheme; this is highly subjective opinion, and there is a lot of debate on the subject if you search SO. Personally I opt for the underscore prefix on private fields such as private GameObject _canvas;, this makes me have zero doubt that I haven't forgotten athisbecause inherently the parameters and fields would have distinct and unique naming schemes.
Take my advice with a grain of salt! There are many many ways to approach a problem, so ultimately go with what is most comfortable for you.