As an answer to the comment by @Richard Law, the name of the virtual rtree table that contains the spatial index in GeoPackage is always named according to template
rtree_[table_name]_[geometry_column_name]
Therefore you can make a SQL query that checks the existence of the rtree table.
For example you can check if table "table1" has a spatial index with ogrinfo
ogrinfo -sql "SELECT EXISTS(SELECT 1 FROM sqlite_master WHERE tbl_name like 'rtree_table1_%') as has_spatial_index" mygeopackage.gpkg
INFO: Open of `mygeopackage.gpkg'
using driver `GPKG' successful.
Layer name: SELECT
Geometry: None
Feature Count: 1
Layer SRS WKT:
(unknown)
has_spatial_index: Integer (0.0)
OGRFeature(SELECT):0
has_spatial_index (Integer) = 1
In this case the spatial indes does exist. Otherwise the would have been "0".
In GeoPackage a table can have only one geometry field and therefore it is enough to make a check by just "rtree" and name of the table without knowing the name of the geometry field as rtree_table1_%
.